package exercise.jslide.jslide.command;

import exercise.jslide.jslide.app.AppContext;

import java.util.Stack;

/**
 * {@code UndoManager} 类负责管理撤销和重做操作。
 * 它维护两个栈：
 * <ul>
 *     <li>undoStack：用于存储执行过的命令，以便撤销操作</li>
 *     <li>redoStack：用于存储撤销过的命令，以便重做操作</li>
 * </ul>
 */
public class UndoManager {
    private Stack<Command> undoStack;
    private Stack<Command> redoStack;

    /**
     * 该构造方法用于初始化 {@code  UndoManager} 对象。
     * 在构造方法中，初始化了 {@code undoStack} 和 redoStack 两个栈。
     */
    public UndoManager() {
        undoStack = new Stack<>();
        redoStack = new Stack<>();
    }

    /**
     * 执行命令，并将命令推入撤销栈，同时清空重做栈。
     *
     * @param command 要执行的命令
     */
    public void executeCommand(Command command) {
        command.execute();
        undoStack.push(command);
        redoStack.clear();
    }

    /**
     * 撤销操作，从撤销栈中弹出一个命令，并执行其撤销操作，同时将命令推入重做栈。
     */
    public void undo() {
        if (!undoStack.isEmpty()) {
            Command command = undoStack.pop();
            command.undo();
            redoStack.push(command);
        }
    }

    /**
     * 重做操作，从重做栈中弹出一个命令，并执行其重做操作，同时将命令推入撤销栈。
     */
    public void redo() {
        if (!redoStack.isEmpty()) {
            Command command = redoStack.pop();
            command.redo();
            undoStack.push(command);

        }
    }

    /**
     * 判断是否可以撤销操作。
     * @return 如果可以撤销操作，返回 true；否则返回 false。
     */
    public boolean canUndo() {
        return !undoStack.isEmpty();
    }

    /**
     * 判断是否可以重做操作。
     * @return 如果可以重做操作，返回 true；否则返回 false。
     */
    public boolean canRedo() {
        return !redoStack.isEmpty();
    }
}